﻿using AdminModels;
using Common;
using Entities;
using Entities.CoinEntities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoinModels
{
    public class PoolCoin : iBasicCoinValues
    {
        public int ID { get; set; }

        public string primarycode { get; set; }

        public string secondarycode { get; set; }

        public double avg { get; set; }

        public double low { get; set; }

        public double high { get; set; }

        public double vol { get; set; }

        public DateTime Created { get; set; }

        public double StdDevAvg { get; set; }

        public double StdDevLow { get; set; }

        public double StdDevHigh { get; set; }

        private string marketsString { get; set; }

        private MarketDataWrapper markets { get; set; }

        public MarketDataWrapper Markets
        {
            get
            {
                if (markets == null)
                {
                    markets = new MarketDataWrapper();
                }
                if (markets.MarketData == null)
                {
                    markets.MarketData = new List<Enums.Markets>();
                }
                return markets;
            }

            private set
            {
                Markets = value;
            }
        }

        public bool AddMarket(Enums.Markets market)
        {
            bool suceeded = false;
            if (!Markets.MarketData.Contains(market))
            {
                Markets.MarketData.Add(market);
                marketsString = JsonConvert.SerializeObject(Markets);
                suceeded = true;
            }

            return suceeded;
        }

        public static bool PersistCoinCollection(List<PoolCoin> coinsToPersist)
        {
            bool success = false;
            Exception exc = null;

            using (AegirContext db = new AegirContext())
            {
                foreach (PoolCoin item in coinsToPersist)
                {
                    db.Pool_Coin.Add(ConvertToEntity(item));
                }
                try
                {
                    db.SaveChanges();
                    success = true;
                }
                catch (Exception ex)
                {
                    success = false;
                    exc = ex;
                    throw;
                }
            }

            //if (exc != null)
                //ErrorLog.SaveLog(exc, "Pool.Coin", ErrorType.Persistance);

            return success;
        }

        private static PoolCoinEntity ConvertToEntity(PoolCoin model)
        {
            PoolCoinEntity entity = new PoolCoinEntity();

            // TODO: Validation
            entity.id = model.ID;
            entity.primarycode = model.primarycode;
            entity.secondarycode = model.secondarycode;
            entity.avg = model.avg;
            entity.low = model.low;
            entity.high = model.high;
            entity.vol = model.vol;
            entity.markets = model.marketsString;
            entity.created = model.Created;
            entity.stddevavg = model.StdDevAvg;
            entity.stddevlow = model.StdDevLow;
            entity.stddevhigh = model.StdDevHigh;

            return entity;
        }

        public static List<PoolCoin> GetMostRecentCoins()
        {
            List<PoolCoin> coins = new List<PoolCoin>();

            using (AegirContext db = new AegirContext())
            {
                var tempCoins = db.Pool_Coin.OrderByDescending(x => x.created).ToArray();
                DateTime recentTime = tempCoins.First().created;

                var coinModels = tempCoins.Where(x => x.created == recentTime).ToList();
                foreach (var model in coinModels)
                {
                    coins.Add(ConvertToModel(model));
                }
            }

            return coins;
        }

        public static PoolCoin ConvertToModel(PoolCoinEntity entity)
        {
            PoolCoin model = new PoolCoin();

            model.ID = entity.id;
            model.primarycode = entity.primarycode;
            model.secondarycode = entity.secondarycode;
            model.avg = entity.avg;
            model.low = entity.low;
            model.high = entity.high;
            model.vol = entity.vol;
            model.Created = entity.created;
            model.StdDevAvg = entity.stddevavg;
            model.StdDevLow = entity.stddevlow;
            model.StdDevHigh = entity.stddevhigh;

            if (model.markets != null)
            {
                MarketDataWrapper markets = JsonConvert.DeserializeObject(entity.markets,
                    typeof(MarketDataWrapper), DefaultValues.GetJsonSettings()) as MarketDataWrapper;
                foreach (var market in markets.MarketData)
                {
                    model.AddMarket(market);
                }
            }

            return model;
        }

       [JsonObject]
       public class MarketDataWrapper
       {
           [JsonProperty]
           public List<Enums.Markets> MarketData { get; set; }
       }
    }
}
